import { _decorator, Node, BoxCollider2D, Animation, Component, ERigidBody2DType, RigidBody2D, Size, Sprite, UITransform, Vec2, Vec3, tween } from 'cc';
import DataManager from '../Runtime/DataManager';
import { DIRECTION_ENUM } from '../../Enums';
import { createPlaceholder, createUINode, destroyNode, getFrameAsset, roundToNearestInteger } from '../utils';
import { ExplosionTimingManager } from './ExplosionTimingManager';
const { ccclass } = _decorator;

@ccclass('BaseProperty')
export class BaseProperty extends Component {
    targetX: number = 0
    targetY: number = 0
    temp_targetX: number = 0
    start_x: number = 0 //吐出来时的坐标
    start_y: number = 0//吐出来时的坐标
    user_direction: DIRECTION_ENUM = null //从哪个方向出现的
    parent_node: Node = null //哪个角色吐出来的
    temp_targetY: number = 0
    speed: number = 10
    direction: DIRECTION_ENUM
    initiate_update: Boolean = false //是否执行调整位置的函数
    is_running: Boolean = false //是否正在移动
    touch_jelly: Boolean = false //是否碰到了果冻
    spring_back: Boolean = false //是否碰到了果冻回弹后的道具
    spring_number: number = 0 //回弹的次数
    pre_position: Vec3
    spriteName
    initialization(spriteName) {
        this.spriteName = spriteName
        let tile = this.node
        let { width, height, position } = DataManager.Instance
        const transform = tile.getComponent(UITransform)
        transform.setContentSize(width, height)
        const rigidBody2D = tile.addComponent(RigidBody2D)
        rigidBody2D.type = ERigidBody2DType.Static
        rigidBody2D.fixedRotation = true
        rigidBody2D.enabledContactListener = true
        rigidBody2D.gravityScale = 0
        const boxCollider2D = tile.addComponent(BoxCollider2D)
        boxCollider2D.offset = new Vec2(0, -28)
        boxCollider2D.size = new Size(width, position)
        const sprite = tile.addComponent(Sprite)
        sprite.sizeMode = Sprite.SizeMode.CUSTOM
        sprite.spriteFrame = getFrameAsset(DataManager.Instance.mapAssets, spriteName).spriteFrame
    }
    // 获取最近距离的x和y
    getNearPosition(direction) {
        let { x, y } = this.node.getPosition()
        let { width, position } = DataManager.Instance
        let tempX = x, tempY = y
        let powerX, powerY
        if (direction == DIRECTION_ENUM.TOP || direction == DIRECTION_ENUM.BOTTOM) {
            powerY = roundToNearestInteger(y / position)
            tempY = powerY * position
        } else if (direction == DIRECTION_ENUM.LEFT || direction == DIRECTION_ENUM.RIGHT) {
            powerX = roundToNearestInteger(x / width)
            tempX = powerX * width
        }
        this.targetX = Math.round(tempX / 10) * 10
        this.targetY = Math.round(tempY / 10) * 10
        this.temp_targetX = this.targetX
        this.temp_targetY = this.targetY
        this.initiate_update = true
        this.direction = direction
    }
    getSendData() {
        let x = 0
        let y = 0
        let destroy = true
        let remainingTime = 10
        let index=0
        if (this.node && this.node.isValid) {
            destroy = false
            x = Math.round(this.node.getPosition().x / this.speed) * this.speed// 位置
            y = Math.round(this.node.getPosition().y / this.speed) * this.speed
            if (this.node.name.includes("bomb")) {
                remainingTime = this.node.getComponent(ExplosionTimingManager).remainingTime
            }
            index=this.node?.getSiblingIndex()
        }
        return {
            destroy,
            x,// 位置
            y,
            remainingTime,
            index
        }
    }
    setSendData(data) {
        if (this.node && this.node.isValid) {
            if (data.destroy) {
                // 如果是砖头执行销毁动画
                if (data.node.includes("brick")) {
                    // 播放破碎动画，动画结束后销毁元素
                    const animation = this.node.getComponent(Animation)
                    animation.play()
                    animation.on(
                        Animation.EventType.FINISHED,
                        this.onBrickFinished,
                        this
                    );
                } else if (data.node.includes("bomb")) {
                    const blastNode = createUINode("blastNode")
                    blastNode.setParent(this.node)
                    blastNode.setScale(2.4, 2.4)
                    const animation = blastNode.addComponent(Animation)
                    const sprite = blastNode.addComponent(Sprite)
                    sprite.sizeMode = Sprite.SizeMode.TRIMMED
                    animation.defaultClip = DataManager.Instance.blast_clip
                    animation.play()
                    DataManager.Instance.audioMgr.playOneShot(DataManager.Instance.audio.find(item => item.name == '1237'))
                    animation.on(
                        Animation.EventType.FINISHED,
                        this.onBlastFinished,
                        this
                    );
                } else {
                    destroyNode(this.node)
                }
            }else{
                if (this.node.name.includes("bomb")) {
                    if (data.remainingTime != 10) {
                        let explosionTimingManager = this.node.getComponent(ExplosionTimingManager)
                        explosionTimingManager.playBombAnimation(true,data.remainingTime)
                    }
                }
                this.node.setSiblingIndex(data.index)
                // 播放位移动画
                tween(this.node)
                    .to(.1, { position: new Vec3(data.x, data.y, 0) })
                    .start()
            }
        }
    }
    onBlastFinished(type: Animation.EventType, state) {
        createPlaceholder(state._targetNode.parent)
        destroyNode(state._targetNode._parent)
    }
    onBrickFinished(type: Animation.EventType, state) {
        createPlaceholder(state._targetNode)
        destroyNode(state._targetNode)
    }
    update() {
        if (this.is_running) {
            let rigidBody2D = this.node.getComponent(RigidBody2D)
            let { x, y } = rigidBody2D.linearVelocity
            if (Math.abs(x) <= 0.5 && Math.abs(y) <= 0.5) {
                if (!this.initiate_update) {
                    let { x: nodeX, y: nodeY } = this.node.getPosition()
                    let { x: otherX, y: otherY } = this.pre_position
                    this.touch_jelly = false
                    let direction
                    if (otherX == nodeX) {
                        if (nodeY > otherY) {
                            direction = DIRECTION_ENUM.BOTTOM
                        } else {
                            direction = DIRECTION_ENUM.TOP
                        }
                    } else {
                        if (parseInt(otherY + 30 + '') >= nodeY - 3 || parseInt(otherY + 30 + '') <= nodeY - 3) {
                            if (nodeX > otherX) {
                                direction = DIRECTION_ENUM.LEFT
                            } else {
                                direction = DIRECTION_ENUM.RIGHT
                            }
                        }
                    }
                    this.getNearPosition(direction)
                }
            } else {
                this.pre_position = this.node.getPosition()
            }
        }
        if (this.initiate_update) {
            this.movePosition()
        }
    }
    // 把道具移动到距离最近的格子上
    movePosition() {
        let { x, y } = this.node.getPosition()
        let { targetX, targetY } = this
        let rigidBody2D = this.node.getComponent(RigidBody2D)
        let lv = rigidBody2D!.linearVelocity;
        y = Math.round(y / this.speed) * this.speed
        x = Math.round(x / this.speed) * this.speed
        targetX = Math.round(targetX / this.speed) * this.speed
        targetY = Math.round(targetY / this.speed) * this.speed

        if (targetX != 0) {
            if (x > parseInt(targetX + '')) {
                lv.x = -this.speed;
                lv = new Vec2(lv.x, 0);
            } else if (x < parseInt(targetX + '')) {
                lv.x = +this.speed;
                lv = new Vec2(lv.x, 0);
            } else {
                this.targetX = 0
            }
        }
        if (targetY != 0) {
            if (y < parseInt(targetY + '')) {
                lv.y = +this.speed;
                lv = new Vec2(0, lv.y);
            } else if (y > parseInt(targetY + '')) {
                lv.y = -this.speed;
                lv = new Vec2(0, lv.y);
            } else {
                this.targetY = 0
            }
        }
        if (targetX == 0 && targetY == 0) {
            this.node.setPosition(Math.round(this.temp_targetX / 10) * 10, (Math.round(this.temp_targetY / 10) * 10) - 2)
            this.temp_targetX = 0
            this.temp_targetY = 0
            this.initiate_update = false
            const boxCollider2D = this.node.getComponent(BoxCollider2D)
            // 撞到果冻的话，再给一个反的推力
            if (this.touch_jelly) {
                boxCollider2D.size = new Size(DataManager.Instance.width - 14, DataManager.Instance.position - 14)
                let forceY = 0, forceX = 0
                switch (this.direction) {
                    case DIRECTION_ENUM.TOP:
                        forceY = 12
                        break;
                    case DIRECTION_ENUM.BOTTOM:
                        forceY = -12
                        break;
                    case DIRECTION_ENUM.LEFT:
                        forceX = -12
                        break;
                    case DIRECTION_ENUM.RIGHT:
                        forceX = 12
                        break;
                }
                lv = new Vec2(forceX, forceY)
                this.touch_jelly = false
                this.spring_back = true
                if (this.node.name.includes("heavy")) {
                    rigidBody2D.linearDamping = 2 * this.spring_number
                } else {
                    rigidBody2D.linearDamping = .8 * this.spring_number
                }
            } else {
                DataManager.Instance.audioMgr.playOneShot(DataManager.Instance.audio.find(item => item.name == '1243'))
                lv = new Vec2(0, 0)
                rigidBody2D.type = ERigidBody2DType.Static
                boxCollider2D.size = new Size(DataManager.Instance.width - 4, DataManager.Instance.position - 4)
                boxCollider2D.restitution = 1
                boxCollider2D.sensor = false
                boxCollider2D.offset = new Vec2(0, -28)
                this.spring_back = false
                if (this.is_running) {
                    this.is_running = false
                }
                this.node.name = this.node.name.replace("Attack", "")
                this.start_x = 0
                this.start_y = 0
                this.user_direction = null
                this.parent_node = null
                // DataManager.Instance.async_scence.push({ type: 'property', parent: this.node.parent, node: this.node.name, player: this })
            }
            boxCollider2D.apply()
        }
        rigidBody2D!.linearVelocity = lv;
    }

}


